﻿/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

using System.Runtime.CompilerServices;

using System.Windows;
using System.Windows.Browser;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Silverlight;
using System.Json;

[assembly: ExtensionType(typeof(HtmlDocument), typeof(HtmlDocumentExtension))]
[assembly: ExtensionType(typeof(HtmlElement), typeof(HtmlElementExtension))]
[assembly: ExtensionType(typeof(FrameworkElement), typeof(FrameworkElementExtension))]
[assembly: ExtensionType(typeof(Gestalt.App), typeof(Gestalt.AppExtension))]
[assembly: ExtensionType(typeof(JsonValue), typeof(Gestalt.JsonValueExtension))]

namespace Gestalt
{

    /// <summary>
    /// Injects properties into the HtmlDocument object for each element ID
    /// </summary>
    public static class HtmlDocumentExtension
    {
        [SpecialName]
        public static object GetBoundMember(HtmlDocument doc, string name)
        {
            HtmlElement result = doc.GetElementById(name);
            if (result == null)
            {
                return OperationFailed.Value;
            }
            return result;
        }
    }

    /// <summary>
    /// Injects properties for getting/setting the attributes of HtmlElement
    /// </summary>
    public static class HtmlElementExtension
    {
        [SpecialName]
        public static object GetBoundMember(HtmlElement element, string name)
        {
            var result = element.GetProperty(name);
            if (result == null)
            {
                return OperationFailed.Value;
            }
            else return result;
        }

        // TODO: should this be SetMemberAfter?
        [SpecialName]
        public static void SetMember(HtmlElement element, string name, string value)
        {
            element.SetProperty(name, value);
        }
    }

    /// <summary>
    /// Injects child XAML objects as properties
    /// </summary>
    public static class FrameworkElementExtension
    {
        [SpecialName]
        public static object GetBoundMember(FrameworkElement element, string name)
        {
            object result = element.FindName(name);
            if (result == null)
            {
                return OperationFailed.Value;
            }
            return result;
        }
    }

    /// <summary>
    /// Injects child XAML objects as properties
    /// </summary>
    public static class AppExtension
    {
        [SpecialName]
        public static object GetBoundMember(object element, string name)
        {
            object result = ((GestaltApp)element)[name];
            if (result == null)
            {
                return OperationFailed.Value;
            }
            return result;
        }
    }

    public static class JsonValueExtension
    {

        [SpecialName]
        public static object GetBoundMember(JsonValue val, string name)
        {
            var item = val[name];
            if (item == null)
            {
                return OperationFailed.Value;
            }
            if (item is JsonValue)
            {
                var type = item.JsonType;
                if (type == JsonType.Number) return double.Parse(item.ToString());
                if (type == JsonType.Boolean) return bool.Parse(item.ToString());
                if (type == JsonType.String)
                {
                    var s = item.ToString().Trim();
                    if (s[0] == '"' && s[s.Length - 1] == '"')
                        return s.Substring(1, s.Length - 2);
                    else
                        return s;
                }
                else return item;
            }
            else return item;
        }

    }
}
